I'm inspired to write this post because Someone Is Wrong On The Internet. Of course a more accurate statement would be "I disagree with some aspects of what someone on the internet said, even though they have an entirely valid point of view". But that's less catchy.
I saw a Tweet I agreed vehemently with, so I retweeted it:
I can't say this enough.
You will read code more than you write code.
Learn to get good at it.
— Laurie (@laurieontech) August 31, 2020
A number of replies to my retweet said variations on this theme:
I'd rather say, learn to write READABLE code !
— Devesh Mankar (@Devz15) August 31, 2020
Yes, and, possibly even more importantly:
Learn to write code that is easy to read. (Yes, easy-to-read code is often harder to write. Do it anyway.)
— Brian Goetz (@BrianGoetz) August 31, 2020
(Note: I have the greatest respect for Brian Goetz, and I don't disagree with the sentiments expressed in any of the Tweets embedded in this post. But I do feel very strongly that there is more to the story. Read on...)
The problem is not that we shouldn't write readable code. Of course we should aim to write readable code, if only for our own poor selves further down the line (there is no one less capable of reading my code the following week than me). The problem is that these two issues are not mutually exclusive. It's not "write readable code" or "learn to read code". That's like saying, "I'm going to drive really economically so I don't need to put petrol in the car". No. You're still going to need to put fuel in the car (if it's not electric!) at some point no matter how economically you drive.
Similarly, no matter how much you try to write code that's readable, and no matter how hard everyone else around you tries to do the same, the reality of life is you will have to read code that you find difficult to understand at some point in your career. Like, probably today.
Let's look at the problems with the approach of "just write readable code".
1. It's wrong to assume someone wrote unreadable code
Yea, I agree to the point of being able to read under the hood open source code of an API used in your app, or you need to take handover from other dev, but getting handover of an UNCLEAN code for further development should be discouraged.
— Devesh Mankar (@Devz15) August 31, 2020
It's just plain wrong to assume "unreadable code" was the output of someone smashing away at the keyboard and not caring about one of the consumers of the code, i.e. other programmers. Code that's hard to understand is often a result of an accumulation of things:
- The code was written at a time when the language/framework didn't do then what it does now;
- The code was written a while back and the fashions and "best practices" back then were different;
- Each line of code was written with readability in mind, but over time as more lines got added, the overall message was lost;
- People moved on and moved away, and now you haven't got anyone to ask about the business or technical reasons behind something (and of course the documentation is horribly out of date).
...etc etc. No one writes unreadable code on purpose. You can see this for yourself if you have a project that only you contribute code to - every time you come back to it after an absence of months, weeks, or even days, you wonder what on Earth you were thinking when you wrote it, because now you know a much better way of doing the same thing, or you have a name which is much clearer for this method.
That's just not reality for large enterprise applications. It's not a case of "handover" or "unclean", it's a case of a large, mature, codebase written by many people with evolving technologies, styles and fashions. That's the reality many live in.
— Trisha Gee (@trisha_gee) August 31, 2020
2. It's a narrative of blame and it doesn't solve anything
The narrative of "unreadable code is the fault of the code author, you should be writing readable code" focuses on placing blame rather than looking at how to deal with the issue. It's easy to blame the author for writing something bad, and to make a pledge to only write readable code ourselves. It's much harder to put aside our ego and think "right, the skill I need now is the skill of learning this new dialect in the code and deciphering what the intent was". Yes, it's fun to feel good about ourselves by grumbling about the quality of the code we've inherited, but it's not getting us anywhere.
Imagine if Baz Luhrmann thought "that Shakespeare guy couldn't spell, and iambic pentameter makes it really hard to understand his plays. I don't think I'll bother getting to grips with Romeo & Juliet, Shakespeare should have written it better". We would have missed out on a unique film just because the original story isn't "readable" by today's standards.
And also learn how to be kind and caring to the reader
— DiegoEH (@DiegoDeRosario) August 31, 2020
Yes, we should write readable code to be considerate of the reader (who might be future-us). We should also be kind and caring to the authors of the code, and learn to accept the code as it is. A true professional learns the dialect(s) of their code base. A true professional has empathy for the contributors to the code. This will help them to better understand why things are the way they are, and only then can they figure out the best way to move forward.
3. Readable code is subjective
I can't assume that what I think is readable is something you can understand immediately. My idea of readability, like a code base's un-readability, is an accumulation of my experiences. I've worked at a bunch of different places using a bunch of frameworks and patterns. If I'm dumped into an unfamiliar (Java) code base that uses any of these, I'll have a decent idea straight away what's going on. But stick me in a modern JavaScript application and I will likely be lost - I can read and understand code line-by-line but my ability to grasp common patterns or the bigger picture will be much more limited than an experienced developer. Of course useful method and variable names, short methods, an intentional design and so on should make it easier to understand. But it doesn't magically overcome my lack of familiarity with a particular language, framework, pattern or business domain.
By all means, make the reader's job as simple as you can, but you can't assume that just because you wrote code that you think is clean and readable that all developers will be able to understand it.
Reading code is a skill
Which brings me to the final, and also original, point. Reading code is a skill. Reading code is a skill that can be learnt, and can be improved. Time, experience, practice, with different languages, frameworks and libraries; different code bases; different programming styles; different patterns, will improve your ability to read code. I couldn't read Spanish eight years ago, now I can follow most written content. Reading Spanish turns out to be something that gets easier with practice (who knew?). It's the same with code. Of course, we read code all the time, whether it's in our code base or StackOverflow, or blogs or books or whatever, so that's a great start - we will get better at reading code simply by doing our job. But it's not enough. Kathy Sierra talks about "deliberate practice" in Making Users Awesome. We get significantly better with deliberate practice than through simple exposure.
Reading code is a skill that we can improve with practice. Next time we see code that we don't understand, we shouldn't beat up the author for "not writing readable code". We shouldn't beat ourselves up for being stupid for not understanding it, because we all come with our own unique experiences. We can instead see it as an opportunity to practice reading this particular code, and leveling up our "reading code" skill.
In Summary
- Reading code is a skill.
- Encouraging developers to "write readable code" does not take away the need for developers to level up their "reading code" skill.
- And of course you should write readable code.
Also, I have a whole talk on this topic, which I guess is how strongly I feel about it. On that page you'll also find a bunch of links to other useful talks and articles.
Everything you said rings true. I remember reading music ages ago and it was HARD. Now… after decades of practice, well, it can still be hard, but not as bad!
I do want to say the most shocking part of your article was you filed it under Rant. I thought, “This is a rant?!” It did not read as a rant but it made me think, that is either just my opinion, or, perhaps it started as a rant but as you thought through it, and wrote this, it became this very great discussion on reading and writing code.
I must read more of your stuff!
Thank you!
It’s classed as a “rant” because it was inspired by me being annoyed with something 🙂
A real rant includes the phrase, “And another thing!” at least once.
So true!
The thing about written music is that it’s relatively opinionated compared to written code.
In music notation, even when there’s a multitude of ways to express a piece, there is still usually a “finite” number of ways to express it.
In programming, this isn’t the case; It’s more freeform, closer to writing a book.
It would definitely be very easy to write a story that is hard to follow, whereas with music, if a trained reader cannot understand it, then it is probably malformed.
True! Good read.
I remember the first time I had to read through a substantial portion of a code base to fix some bugs, modernize it and port it to a new language. It was affectionately referred to as “Bob’s Code” (name changed). At first I was really annoyed at how “bad” the code was written, the logic and the choice of languages. But as I got deeper and deeper into the code, I realized several things: the code was written over 20+ years, it grew “organically”, Bob had been a scientist that made a transition into full-time developer, the scope of the problem had changed over time, available tools and languages also changed over time, etc. Over time, my annoyance turned into understanding and empathy. And I’m pretty sure there’s a developer out there somewhere right now that’s annoyed with code that I wrote.
Thanks for the nice “rant”.
I love this story, I think we’ve all had to work on some applications like this at some time. It has taken me the longest time to get over the “I’m so annoyed about this code!” and move towards “it is what it is, let’s get the job done”.
You need to read code in multiple languages because, at some point in your life, you will encounter code that you need to understand, no matter if it was written to be read of not.
For example, I tried to modify a program that had been written by a German group using PHP, with and without CSS style imposed, Java, Javascript, and some C#. It also made use of wrappers around calls to subroutines that called other subroutines.
To add to the confusion, at least three different groups had modified segments of the code. The manual that was available only addressed the operation. No theory of ops or architectural explanation was available–not even in German. At least one of the modifying groups abandoned their work before they completed it.
To say that it was a ball of snakes is an understatement. I was able to unwind some of the twisted code with considerable help from a consultant–enough to make the changes requested. However, it took about four times as long as I expected.
As was mentioned in another response, legacy code will force you to learn legacy programming and coding.
Trisha, this is a great read, thanks!
When I’m asked to speak to kids in middle or high school about my profession – programming, the teacher in the classroom always asks, “What should the students concentrate on in school?”
My answer is always “Learn to read. No really, learn to devour everything put in front of you.”
When I talk to new programmers I give the same answer but for them I include, “And learn to read any source code put in front of you.”
We all had to learn to read English. Even fantastic English doesn’t read itself. The same is true of source code.
Indeed working on a very large project that’s only 5 years old, and I believe at first the architecture, code organization and readability were optimum, but with additional needs and over time, things got more and more complicated, thus less and less easy to read. Today when one arrives on the project, they just get horrendous headaches…
The ability to read code evolves with practice and time, and I think there’s also an experience-on-the-project parameter to take into account (you get better at reading a particular projects’ code the more you dive into it). So you never stop learning. Yay, that’s why we chose IT right?
Hey there just wanted to give you a quick heads up and let you know a few of the pictures aren’t loading properly.
I’m not sure why but I think its a linking issue.
I’ve tried it in two different web browsers and both show the same results.
In this specific post? Or in some of my other blog posts? Some of the older blog posts haven’t been fully migrated yet, (I’m currently migrating posts from two previous blog platforms!), I’m still working on it
As your experience in programming grows you understand code better because that you learned the “best” solutions and patterns and you can recognize them then they are used by others.
If someone is not following them then your experience is less useful, there is no familiar abstraction to aid to the readability.
But the deeper point is that if a piece of code is well documented I will not have to understand it in order to use it, or refactor it, I can simply read the documentation.
It’s Sturgeon’s Law – 90% of everything is crap.
Lots of programmers make work for everyone, by making up complicated frameworks that take a lot of knowledge and deliver very little, or by using hard-to-reason about features like template metaprogramming when a much simpler solution would do.
I’ve read easily millions of lines of code, and by now I’m fairly sure that there’s no code I can’t eventually figure out. However, some significant portion of the code I read is written by thoughtful and responsible professionals, and the gap between that and everything else is huge.